"""
    Computational Economics
    3.1: NumPy
    http://johnstachurski.net/lectures/numpy.html

    DEFINITIONS


    REFERENCES


    PROBLEM

    Consider evaluating the polynomial

        p(x) = a0 + a1x + a2x^2 + aNx^N = sum(n=0->N)anx^n (x as R)

    at some x given the vector of coefficients

    We can do this using np.poly1d, but for the sake of the exercise don't use
    this class

    We also want to avoid for and while loops, which are slow

    Write a function which takes the vector of coefficients and a number x,
    and returns the value p(x)

        * Hint: Use np.cumprod()

"""

import numpy as np



def f(a, n, x):
    if n == 0:
        return a
    else:
        return a * x**n

def poly1d(a, x):
    return sum([f(a,n,x) for n, a in enumerate(a)])

def poly1d_(a, x):
    x_map = np.empty(len(a))
    x_map[0] = 1
    x_map[1:] = x
    cum_x = np.cumprod(x_map)
    return np.dot(a, cum_x)


def stachurski(coef, x):
    X = np.empty(len(coef))
    X[0] = 1
    X[1:] = x
    Y = np.cumprod(X)   # Y = [1, x, x**2,...]
    return np.dot(coef, Y)


def main():
    coef = [2, 0, -4, -8, 18]
    x = 2
    assert poly1d(coef, x) == stachurski(coef, x) == poly1d_(coef, x)



#
# MAIN
#
if __name__ == "__main__":
    main()
    print '%s: ok' % (__file__)
